#include "Candidate.h"
#include "QDebug"
#include "RandomNumberGenerator.h"

Candidate::Candidate() {
    this->fitness = 0;
}
Candidate::Candidate(int genomeSize, float fitness)
{
    this->genomeSize = genomeSize;
    this->fitness = fitness;
    this->finalValue = 0;
}
Candidate::Candidate(std::vector<float> genome) {
    this->genome = genome;
    this->fitness = 0;
    this->finalValue = 0;
}

Candidate::~Candidate() {
    this->genome.clear();
}
void Candidate::clone(Candidate* parent) {
    this->genomeSize = parent->getGenome().size();
    this->fitness = parent->getFitness();
    this->finalValue = parent->finalValue;
    this->genome = parent->getGenome();
}

void Candidate::swapSubString(Candidate* mate, int crossoverIndex) {
    std::vector<float> tempGenome;
    for(int i=0;i<crossoverIndex;i++) {
        tempGenome.push_back(this->getChromosome((i)));
        this->genome.at(i) = mate->getChromosome(i);
        mate->setChromosome(i,tempGenome.at(i));
    }
    tempGenome.clear();
}
void Candidate::mutate(float mutationRate,float mutationAmount) {
    if(RandomNumberGenerator::nextFloat(1) < mutationRate) {
        for(int i = 0; i <= mutationAmount; i++) {
            this->setChromosome(RandomNumberGenerator::nextInt(getLength()),RandomNumberGenerator::nextFloat(2));
        }
    }
}
void Candidate::extremalOptimization(int chromosome) {

}

void Candidate::printGenome() {
    QString printString;
    printString.append("[");
    for(int i=0;i<this->genome.size();i++) {
        printString.append((new QString())->setNum(this->genome.at(i)));
        printString.append(",");
    }
    printString.append("]");
    qDebug() << printString;
    //qDebug() << this->genome.size();
}
void Candidate::variation() {

}

std::vector<float> Candidate::getGenome() {
    return this->genome;
}
float Candidate::getChromosome(int index) {
    return this->genome.at(index);
}
void Candidate::setChromosome(int index, float value) {
    this->genome.at(index) = value;
}
void Candidate::addChromosome(float value) {
    this->genome.push_back(value);
}

void Candidate::setFitness(float fitness) {
    this->fitness = fitness;
}
float Candidate::getFitness() {
    return this->fitness;
}
int Candidate::getLength() {
    return this->genomeSize;
}
void Candidate::setFinalValue(float finalValue) {
    this->finalValue = finalValue;
}
float Candidate::getFinalValue() {
    return this->finalValue;
}
